package org.example;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * 数据库工具类 - 提供连接管理、资源关闭等基础功能
 * 版本：1.2
 * 更新说明：
 * 1. 增强异常处理机制
 * 2. 优化资源关闭顺序
 * 3. 增加连接有效性验证
 */
public class Util {
    // 配置文件路径
    private static final String CONFIG_FILE = "app.properties";
    // 默认连接超时时间（秒）
    private static final int DEFAULT_VALID_TIMEOUT = 5;

    /**
     * 获取数据库连接
     * @return 有效数据库连接
     * @throws RuntimeException 包含所有可能的异常信息
     */
    public static Connection getConn() {
        try (InputStream in = getConfigStream()) {
            Properties prop = loadProperties(in);
            validateConfig(prop);

            // 显式加载驱动（兼容旧版本）
            Class.forName("com.mysql.cj.jdbc.Driver");

            return createConnection(prop);
        } catch (Exception e) {
            throw wrapException("获取数据库连接失败", e);
        }
    }

    /**
     * 验证连接有效性
     * @param conn 数据库连接
     * @param timeout 验证超时时间（秒）
     * @return 连接是否有效
     */
    public static boolean isValidConnection(Connection conn, int timeout) {
        if (conn == null) return false;
        try {
            return conn.isValid(timeout);
        } catch (SQLException e) {
            return false;
        }
    }

    /**
     * 安全关闭数据库资源
     * @param resources 需要关闭的资源（可变参数，支持任意顺序）
     */
    public static void close(AutoCloseable... resources) {
        for (AutoCloseable res : resources) {
            closeQuietly(res);
        }
    }

    //-----------------------------------------------------------
    // 以下为私有工具方法
    //-----------------------------------------------------------

    private static InputStream getConfigStream() {
        InputStream in = Util.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
        if (in == null) {
            throw new RuntimeException("数据库配置文件 [" + CONFIG_FILE + "] 未找到");
        }
        return in;
    }

    private static Properties loadProperties(InputStream in) throws Exception {
        Properties prop = new Properties();
        prop.load(in);
        return prop;
    }

    private static void validateConfig(Properties prop) {
        String[] requiredKeys = {"url", "username", "password"};
        for (String key : requiredKeys) {
            if (!prop.containsKey(key)) {
                throw new RuntimeException("数据库配置缺失: " + key);
            }
        }
    }

    private static Connection createConnection(Properties prop) throws SQLException {
        String url = prop.getProperty("url");
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");

        // 添加连接参数校验
        if (url == null || url.isEmpty()) {
            throw new RuntimeException("数据库URL配置错误");
        }

        return DriverManager.getConnection(url, user, pwd);
    }

    private static void closeQuietly(AutoCloseable res) {
        if (res != null) {
            try {
                res.close();
            } catch (Exception e) {
                // 此处建议使用日志框架记录
                System.err.println("资源关闭异常: " + e.getMessage());
            }
        }
    }

    private static RuntimeException wrapException(String message, Exception cause) {
        return new RuntimeException(message + " - " + cause.getMessage(), cause);
    }

    /**
     * 快速验证连接（使用默认超时时间）
     */
    public static boolean isValidConnection(Connection conn) {
        return isValidConnection(conn, DEFAULT_VALID_TIMEOUT);
    }
}